null 和 undefined 代表著缺少值或未定義的狀態。儘管它們在 JavaScript 中也存在,但在 TypeScript 中,可以使用靜態型別檢查來更好地處理這兩個值,以減少潛在的錯誤。
首先,讓我們簡單地了解一下 null 和 undefined 的定義:
變數的值為空值
。變數尚未賦值,或者該值不存在
。如果一個變數被聲明但未賦值,則它的值就是 undefined。null | undefined |
---|---|
變數的值為空 (缺少值) | 變數的值尚未初始化或該值不存在 |
可以賦值給變數 | 變數聲明後但未賦值時的預設值 |
以下範例:
// null 可以賦值給變數,且它是一個具體的值,表示這變數已經被賦予了空值。
let a: null = null;
let b: string | null = null;
// undefined 通常是變數聲明後但未賦值時的默認值,或者表示變數訪問的屬性或索引不存在時的值。
let a: undefined = undefined;
let b: number; // b 的默認值為 undefined
let c: string | undefined = undefined;
所以如果可以的話,通常建議盡量 為變數賦予初始值
或 使用聯合類型、類型斷言、空值合併運算子 (??)
等來明確表示變數的可能值,以避免出現潛在的錯誤。
例如:
// 使用斷言
let str: string | null = null;
let strLength: number = (str as unknown as string).length;
// 使用空值合併運算子 (??)
let str: string | null = null;
let result = str ?? "我是威爾豬";
console.log(result); // 輸出: 我是威爾豬
初始化變數:
我們可以將變數初始化為 null,以表示它的值尚未被賦值或尚未確定。
let myName: string | null = null;
作為函式的返回值:
有時候,函式需要返回一個值或者表示失敗的情況。
interface IUser {
id: number;
name: string;
}
const userData: IUser[] = [
{ id: 1, name: "威爾豬" },
{ id: 2, name: "威爾羊" },
];
function findUser(id: number): string | null {
const user = userData.filter((item) => item.id === id);
return user ? user[0].name : null;
}
console.log(findUser(1)); // 輸出: null
let data: string | null = "威爾豬";
data = null; // 清除變數的值
假設我們要寫一個除法函式,該函式應該要返回一個數字,但在某些情況下,數字會無法計算:
const divide = (a: number, b: number): number | null =>
b === 0 ? null : a / b;
let result1: number | null = divide(3, 2) || null;
let result2: number | null = divide(3, 0) || null;
console.log(result1); // 輸出: 1.5
console.log(result2); // 輸出: null
初始化變數:
當您聲明一個變數但尚未為它賦值時,它的值默認為 undefined。
let a: number; // 輸出: undefined,因為變數 a 尚未被賦值
函式的參數:
當函式聲明的參數未提供值時,它的值為 undefined。
function greet(name: string): void {
console.log(`哈囉,${name}!`);
}
greet(); // 輸出: 哈囉,undefined!,因為未提供 name 參數的值
函式返回值:
函式如果沒有明確指定返回值,默認返回 undefined。
function handleNothing(): void {}
console.log(handleNothing()); // 輸出: undefined
const mobile = ["Apple", "Samsung", "Mi"];
console.log(mobile[3]); // 輸出: undefined,因為 mobile 陣列中不存在索引值為 3 的元素
const user = { name: "威爾豬" };
console.log(user.age); // 輸出: undefined,因為 user 物件中不存在 age 屬性
避免非必要的賦值為 null 或 undefined:
使用嚴格的比較運算子 (===
或 !==
):
let myName: string | undefined;
if (myName === undefined) myName = "威爾豬";
console.log(myName); // 輸出: 威爾豬
??
),並適當的提供預設值:
const getName = (name?: string): string => name ?? `不認識`; // 避免 undefined
console.log(getName()); // 輸出: 不認識
console.log(getName("威爾豬")); // 輸出: 威爾豬
const getFullName = (
firstName: string,
lastName: string | undefined
): string => {
const useLastName = lastName ?? ""; // 避免 undefined
return `${firstName} ${useLastName}`;
};
console.log(getFullName("威爾", "豬")); // 顯示: 威爾豬
console.log(getFullName("威爾", undefined)); // 顯示: 威爾
函式參數使用可選串連 (?
):
參數為 null 或 undefined 時,使用可選串連會返回 undefined,不會引發錯誤警告。
const message = (message?: string | undefined): void => {
console.log(message);
};
message("哈囉,威爾豬!"); // 顯示: 哈囉,威爾豬!
message(); // 顯示: undefined
const fetchUser = (id?: number | undefined): string | null => {
return id !== undefined ? `威爾豬 ${id} 號` : null;
};
console.log(fetchUser()); // 輸出: null
console.log(fetchUser(1)); // 輸出: 威爾豬 1 號
console.log(fetchUser(2)); // 輸出: 威爾豬 2 號
// tsconfig.json
{
// ... ,
"strictNullChecks": true,
// ... ,
}
如果我們已經開啟了嚴格檢查模式
"strict": true
( 這個配置是嚴格模式的最高權限 ),所以 strictNullChecks 配置就可以不用再開啟了。
整體而言,null 和 undefined 可以使用它們來聲明變數的類型或處理可能缺少值的情況,但通常情況下,null 是開發者自行賦予變數的值,而 undefined 是變數默認的未賦值狀態。所以正確了解 null 和 undefined 的區別,並謹慎使用它們,才能減少潛在的錯誤和不確定性,提高程式碼的可靠性和可維護性。